package com.yonyou.pmclouds.project.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.BeanHelper;
import com.yonyou.pmclouds.basecom.util.ChineseStringUtils;
import com.yonyou.pmclouds.basecom.util.CommonProgramConsts;
import com.yonyou.pmclouds.basecom.util.DateUtils;
import com.yonyou.pmclouds.businessobject.util.BulkDataSplitUtils;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.plan.entity.ProjectPlanViewVO;
import com.yonyou.pmclouds.plan.entity.ScheduleItemVO;
import com.yonyou.pmclouds.plan.entity.ScheduleVO;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleItemQueryService;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleQueryService;
import com.yonyou.pmclouds.procedure.entity.ProcedureRefVO;
import com.yonyou.pmclouds.procedure.mapper.ProcedureMapper;
import com.yonyou.pmclouds.procedure.mapper.ProceprojectMapper;
import com.yonyou.pmclouds.procedure.rmiitf.ProcedureQuery;
import com.yonyou.pmclouds.project.entity.*;
import com.yonyou.pmclouds.project.mapper.ProjectMapper;
import com.yonyou.pmclouds.project.mapper.ProjectStatisticsMapper;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.projectstatus.entity.ProjectStatusVO;
import com.yonyou.pmclouds.projectstatus.rmiitf.ProjectStatusQuery;
import com.yonyou.pmclouds.projecttype.entity.ProjectTypeVO;
import com.yonyou.pmclouds.projecttype.rmiitf.ProjectTypeQuery;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseVO;
import com.yonyou.pmclouds.team.entity.TeamEnterpriseViewVO;
import com.yonyou.pmclouds.team.entity.TeamMemberVO;
import com.yonyou.pmclouds.team.entity.TeamMemberViewVO;
import com.yonyou.pmclouds.team.rmiitf.TeamEnterpriseQuery;
import com.yonyou.pmclouds.team.rmiitf.TeamMemberQuery;
import com.yonyou.pmclouds.workstopreport.rmiitf.WorkStopQuery;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = ProjectSimpleQuery.class)
public class ProjectSimpleQueryImpl implements ProjectSimpleQuery {
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ProjectStatisticsMapper statisticsMapper;
    @Autowired
    private TeamEnterpriseQuery teamEnterpriseQuery;
    @Autowired
    private TeamMemberQuery teamMemberQuery;
    @Autowired
    private ProjectTypeQuery typeQuery;
    @Autowired
    private ProjectStatusQuery statusQuery;
    @Autowired
    private OrganizationQuery organizationQuery;
    @Autowired
    private ProceprojectMapper proceprojectMapper;
    @Autowired
    private ProcedureMapper procedureMapper;
    @Autowired
    private ProcedureQuery procedureQuery;
    @Autowired
    private WorkStopQuery workStopQuery;
    @Autowired
    private IScheduleQueryService scheduleQueryService;
    @Autowired
    private IScheduleItemQueryService scheduleItemQueryService;

    @Override
    public PageObject<ProjectVO> queryByManagerOrCreator(String user, String keyword, Byte state, int start, int offset) throws BusinessException {
        if (offset > CommonProgramConsts.DEFAULT_MAX_QUERY_SIZE) {
            offset = CommonProgramConsts.DEFAULT_MAX_QUERY_SIZE;
        }
        if (offset < CommonProgramConsts.DEFAULT_MIN_QUERY_SIZE) {
            offset = CommonProgramConsts.DEFAULT_MIN_QUERY_SIZE;
        }
        String[] keywords = null;
        keyword = StringUtils.trim(keyword);
        if (!StringUtils.isEmpty(keyword)) {
            keywords = StringUtils.split(keyword, ' ');
            if (ArrayUtils.isEmpty(keywords)) {
                keywords = null;
            } else {
                keywords = ArrayUtils.subarray(keywords, 0, 3);
            }

        }
        int sum = projectMapper.countWithKeywordByManangerOrCreator(user, keywords, RuntimeEnvironment.getTenantId(), state);
        ProjectVO[] projects = projectMapper.queryWithKeywordByManangerOrCreator(user, keywords, RuntimeEnvironment.getTenantId(), state, start, offset);
        // 添加项目状态
        Set<String> states = new HashSet<>();
        Set<String> pkSrcs = new HashSet<>();
        if (ArrayUtils.isNotEmpty(projects)) {
            for (ProjectVO ref : projects) {
                states.add(ref.getPkProjectStatus());
                pkSrcs.add(ref.getPkOrg());
            }
        }

        states.remove(null);
        pkSrcs.remove(null);
        // 处理状态
        if (!states.isEmpty()) {
            Map<String, String> statusNameMap = statusQuery.queryNamesByIds(states.toArray(new String[0]));
            for (ProjectVO ref : projects) {
                if (ref.getPkProjectStatus() != null) {
                    ref.setProjectStatusName(statusNameMap.get(ref.getPkProjectStatus()));
                }
            }
        }
        //处理组织
        if(!pkSrcs.isEmpty()){

            OrganizationVO[] orgs = organizationQuery.queryByPkSrcs(RuntimeEnvironment.getTenantId(), pkSrcs.toArray(new String[0]));
            Map<String, String> orgMap = new HashMap<>();
            for(OrganizationVO org : orgs){
                orgMap.put(org.getPkSrc(), org.getSname());
            }
            if(!orgMap.isEmpty()){
                for (ProjectVO ref : projects) {
                    if(ref.getPkOrg() != null){
                        ref.setOrgName(orgMap.get(ref.getPkOrg()));
                    }
                }
            }

        }
        //判断是否有关联的计划
        if (ArrayUtils.isNotEmpty(projects)) {

            HashMap<String, ProjectVO> key2ProjectVO = new HashMap<>();
            for (ProjectVO project : projects) {
                key2ProjectVO.put(project.getPkProject(),project);
            }

            Map<String, List<ScheduleVO>> pk2ScheduleVO = scheduleQueryService.queryByProjectIds(key2ProjectVO.keySet().toArray(new String[0]));

            for (String pkProject : key2ProjectVO.keySet()) {
                if (pk2ScheduleVO.get(pkProject) != null && pk2ScheduleVO.get(pkProject).size() > 0) key2ProjectVO.get(pkProject).setHasPlan(true);
                else key2ProjectVO.get(pkProject).setHasPlan(false);
            }
        }

        //计算停工天数
        calculateWorkStopDays(projects);

        return new PageObject<>(projects, sum, start);
    }

    private void calculateWorkStopDays(ProjectVO[] projects) {
        for (ProjectVO project : projects) {
            if(project.getProjectState() == ProjectConst.STATE_PAUSE){
                int recent = 0;
                Date currentDate = new Date();
                Date stopDate = project.getWorkstopDate();
                long currentTime = currentDate.getTime();
                long stopTime = stopDate == null ? 0L : stopDate.getTime();
                if(stopDate != null && currentTime >= stopTime ){//已经停工了
                    recent = (int) DateUtils.getDaysBetween(stopDate,currentDate);
                } else{
                    recent = 0;
                }
                project.setWorkstopdays(project.getTotworkstopDays() == null ? 0 : project.getTotworkstopDays() + recent);
            }else{//other status
                //累计停工天数由复工单回写，直接取值就行
                project.setWorkstopdays(project.getTotworkstopDays() == null ? 0 : project.getTotworkstopDays());
            }
        }
    }

    @Override
    public ProjectVO queryProject(String id) {
        // 这里不作权限控制
        return projectMapper.getById(id);
    }

    @Override
    public ProjectViewVO queryProjectViewVO(String pkProject) throws BusinessException {

        ProjectViewVO projectViewVO = getProjectViewVO(pkProject);


        //查询项目对应的工序对象
        ProcedureRefVO[] procedure = procedureQuery.queryRefByProject(pkProject,"");
        //过滤子工序
        ProcedureRefVO[] procefiter = Procefiter(procedure);
        projectViewVO.setProcedure(procefiter);


        if (projectViewVO == null)
            return null;
        // 设置项目状态和项目类型
        String projectTypeId = queryProjectTypeByProject(pkProject);

        String projectStatusId = queryProjectStatusByProject(pkProject);

        String projectTypeName = typeQuery.queryNameById(projectTypeId);

        String projectStatusName = statusQuery.queryNameById(projectStatusId);

        projectViewVO.setProjectTypeName(projectTypeName);

        projectViewVO.setProjectStatusName(projectStatusName);

        if(StringUtils.isNotBlank(projectViewVO.getPkOrg())){
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), projectViewVO.getPkOrg());
            if(null != organizationVO) projectViewVO.setOrgName(organizationVO.getSname());
        }

        TeamEnterpriseVO[] teamEnterpriseVOs = getEnterpriseVOsByProject(pkProject);

        if (ArrayUtils.isEmpty(teamEnterpriseVOs))
            return projectViewVO;

        TeamMemberVO[] teamMemberVOs = getMemberVOsByProject(pkProject);

        setProManagerEnt(projectViewVO, teamMemberVOs);

        Map<String, List<TeamMemberViewVO>> pkEnterAndMemberMap = getPkEnterAndMemberViewMap(teamMemberVOs);

        TeamEnterpriseViewVO[] teamEnterpriseViewVOs = getEnterpriseViewVOs(teamEnterpriseVOs, pkEnterAndMemberMap);

        projectViewVO.setTeamEnterpriseViewVOs(teamEnterpriseViewVOs);

        // 这里不作权限控制
        return projectViewVO;
    }

    //过滤子工序
    private ProcedureRefVO[] Procefiter(ProcedureRefVO[] procedureRefVO){
        if (ArrayUtils.isEmpty(procedureRefVO)){
            return procedureRefVO;
        }
        List<ProcedureRefVO> procedureRefVOS = Arrays.asList(procedureRefVO);
        ArrayList<ProcedureRefVO> procedureList = new ArrayList<>(procedureRefVOS);
        for (int i=0;i<procedureList.size();i++){
            ProcedureRefVO p=procedureList.get(i);
            if (!p.getPkProcedure().equals(p.getPkRoot())){
                procedureList.remove(i);
                i--;
            }
        }
        return procedureList.toArray(new ProcedureRefVO[procedureList.size()]);
    }
    /**
     * 设置项目经理所属的企业ID，该字段用于前端逻辑判断
     */
    private void setProManagerEnt(ProjectViewVO projectViewVO, TeamMemberVO[] teamMemberVOs) {
        for (TeamMemberVO teamMemberVO : teamMemberVOs) {
            if (StringUtils.equals(teamMemberVO.getPkUser(), projectViewVO.getManager())) {
                projectViewVO.setManagerEnt(teamMemberVO.getPkEnterprise());
                break;
            }
        }
    }

    @Override
    public ProjectViewVO queryProjectViewVOByPkSrc(String pkTenant, String pkSrc) throws BusinessException {
        ProjectViewVO projectViewVO = getProjectViewVOByPkSrc(pkTenant, pkSrc);

        if (projectViewVO == null)
            return null;

        String pkProject = projectViewVO.getPkProject();
        //查询项目对应的工序对象
        ProcedureRefVO[] procedure = procedureQuery.queryRefByProject(pkProject,"");
        //过滤子工序
        ProcedureRefVO[] procefiter = Procefiter(procedure);
        projectViewVO.setProcedure(procefiter);
        // 设置项目状态和项目类型
        String projectTypeId = queryProjectTypeByProject(pkProject);

        String projectStatusId = queryProjectStatusByProject(pkProject);

        String projectTypeName = typeQuery.queryNameById(projectTypeId);

        String projectStatusName = statusQuery.queryNameById(projectStatusId);

        projectViewVO.setProjectTypeName(projectTypeName);

        projectViewVO.setProjectStatusName(projectStatusName);

        // 组织名称赋值
        if (StringUtils.isNotBlank(projectViewVO.getPkOrg())) {
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), projectViewVO.getPkOrg());
            if (null != organizationVO) projectViewVO.setOrgName(organizationVO.getSname());
        }

        TeamEnterpriseVO[] teamEnterpriseVOs = getEnterpriseVOsByProject(projectViewVO.getPkProject());

        if (ArrayUtils.isNotEmpty(teamEnterpriseVOs)){
            TeamMemberVO[] teamMemberVOs = getMemberVOsByProject(projectViewVO.getPkProject());

            Map<String, List<TeamMemberViewVO>> pkEnterAndMemberMap = getPkEnterAndMemberViewMap(teamMemberVOs);

            TeamEnterpriseViewVO[] teamEnterpriseViewVOs = getEnterpriseViewVOs(teamEnterpriseVOs, pkEnterAndMemberMap);

            projectViewVO.setTeamEnterpriseViewVOs(teamEnterpriseViewVOs);
        }

        // 这里不作权限控制
        return projectViewVO;
    }

    @Override
    public ProjectVO queryByPkSrc(String pkTenant, String pkSrc) throws BusinessException {
        return projectMapper.queryBySrc(pkTenant, pkSrc);
    }


    /**
     * 根据项目主键查询项目档案
     *
     * @param id
     * @return
     */
    private ProjectViewVO getProjectViewVO(String id) {
        ProjectVO projectVO = projectMapper.getById(id);
        calculateWorkStopDays(new ProjectVO[]{projectVO});
        if (projectVO == null)
            return null;

        ProjectViewVO projectViewVO = new ProjectViewVO();
        for (String field :
                ProjectViewVO.transFields) {
            BeanHelper.setProperty(projectViewVO, field, BeanHelper.getProperty(projectVO, field));
        }
        return projectViewVO;
    }

    @Autowired
    private ProjectStatusQuery projectStatusQuery;
    @Autowired
    private ProjectTypeQuery projectTypeQuery;

    /**
     * 根据项目来源主键查询项目档案
     *
     * @param pkTenant
     * @param pkSrc
     * @return
     */
    private ProjectViewVO getProjectViewVOByPkSrc(String pkTenant, String pkSrc) throws BusinessException {
        ProjectVO[] projectVOs = projectMapper.queryVOBySrcIds(pkTenant, new String[]{pkSrc});

        if (ArrayUtils.isEmpty(projectVOs))
            return null;

        ProjectViewVO projectViewVO = new ProjectViewVO();
        for (String field :
                ProjectViewVO.transFields) {
            BeanHelper.setProperty(projectViewVO, field, BeanHelper.getProperty(projectVOs[0], field));
        }

        ProjectStatusVO statusVO = projectStatusQuery.queryById(projectVOs[0].getPkProjectStatus());

        if (statusVO != null)
            projectViewVO.setProjectStatusName(statusVO.getSname());

        ProjectTypeVO typeVO = projectTypeQuery.queryById(projectVOs[0].getPkProjectType());

        if (typeVO != null)
            projectViewVO.setProjectTypeName(typeVO.getSname());

        return projectViewVO;
    }

    /**
     * 组装参与企业与参与人员的对应关系
     *
     * @param teamEnterpriseVOs
     * @param pkEnterAndMemberMap
     * @return
     */
    private TeamEnterpriseViewVO[] getEnterpriseViewVOs(TeamEnterpriseVO[] teamEnterpriseVOs, Map<String, List<TeamMemberViewVO>> pkEnterAndMemberMap) {
        TeamEnterpriseViewVO[] teamEnterpriseViewVOs = new TeamEnterpriseViewVO[teamEnterpriseVOs.length];

        for (int i = 0; i < teamEnterpriseVOs.length; i++) {
            TeamEnterpriseViewVO teamEnterpriseViewVO = new TeamEnterpriseViewVO();
            for (String field :
                    TeamEnterpriseViewVO.transFields) {
                BeanHelper.setProperty(teamEnterpriseViewVO, field, BeanHelper.getProperty(teamEnterpriseVOs[i], field));
            }

            List<TeamMemberViewVO> memberViewVOList = pkEnterAndMemberMap.get(teamEnterpriseViewVO.getPkEnterprise());

            if (memberViewVOList != null && memberViewVOList.size() > 0) {
                teamEnterpriseViewVO.setTeamMemberViewVOs(memberViewVOList.toArray(new TeamMemberViewVO[memberViewVOList.size()]));
            }

            teamEnterpriseViewVOs[i] = teamEnterpriseViewVO;
        }
        return teamEnterpriseViewVOs;
    }

    /**
     * 根据项目查询参与人员
     *
     * @param id
     * @return
     * @throws BusinessException
     */
    private TeamMemberVO[] getMemberVOsByProject(String id) throws BusinessException {
        TeamMemberVO[] teamMemberVOs = teamMemberQuery.queryByProject(id);

        if(teamMemberVOs == null || teamMemberVOs.length <= 0){
            return new TeamMemberVO[0];
        }

        Arrays.sort(teamMemberVOs, new Comparator<TeamMemberVO>() {
            @Override
            public int compare(TeamMemberVO o1, TeamMemberVO o2) {
                if (o1 == o2) {
                    return 0;
                }
                if (o1 == null) {
                    return 1;
                }
                if (o2 == null) {
                    return -1;
                }
                if (!o1.getUserRole().equals(o2.getUserRole())) {
                    return o1.getUserRole().compareTo(o2.getUserRole());
                }
                int com = ChineseStringUtils.compareInDict(o1.getEnterpriseName(), o2.getEnterpriseName());
                if (com != 0) {
                    return com;
                }
                return ChineseStringUtils.compareInDict(o1.getUserName(), o2.getUserName());

            }
        });
        return teamMemberVOs;
    }

    /**
     * 根据项目查询参与企业
     *
     * @param pkProject
     * @return
     * @throws BusinessException
     */
    private TeamEnterpriseVO[] getEnterpriseVOsByProject(String pkProject) throws BusinessException {
        TeamEnterpriseVO[] teamEnterpriseVOs = teamEnterpriseQuery.queryByProject(pkProject);

        if(teamEnterpriseVOs == null || teamEnterpriseVOs.length <= 0){
            return new TeamEnterpriseVO[0];
        }

        Arrays.sort(teamEnterpriseVOs, new Comparator<TeamEnterpriseVO>() {
            @Override
            public int compare(TeamEnterpriseVO o1, TeamEnterpriseVO o2) {
                if (o1 == o2) {
                    return 0;
                }
                if (o1 == null) {
                    return 1;
                }
                if (o2 == null) {
                    return -1;
                }
                if (!o1.getEntRole().equals(o2.getEntRole())) {
                    return o1.getEntRole().compareTo(o2.getEntRole());
                }
                return ChineseStringUtils.compareInDict(o1.getEnterpriseName(), o2.getEnterpriseName());
            }
        });
        return teamEnterpriseVOs;
    }

    /**
     * 获取企业ID与TeamMemberViewVO的对应关系
     *
     * @param teamMemberVOs
     * @return
     */
    private Map<String, List<TeamMemberViewVO>> getPkEnterAndMemberViewMap(TeamMemberVO[] teamMemberVOs) {
        Map<String, List<TeamMemberViewVO>> pkEnterAndMemberMap = new HashMap<String, List<TeamMemberViewVO>>();

        if (ArrayUtils.isEmpty(teamMemberVOs))
            return pkEnterAndMemberMap;

        String tempPkEnter;

        for (int i = 0; i < teamMemberVOs.length; i++) {
            TeamMemberViewVO teamMemberViewVO = new TeamMemberViewVO();
            for (String field : TeamMemberViewVO.transFields) {
                BeanHelper.setProperty(teamMemberViewVO, field, BeanHelper.getProperty(teamMemberVOs[i], field));
            }

            tempPkEnter = teamMemberViewVO.getPkEnterprise();

            if (pkEnterAndMemberMap.get(tempPkEnter) == null) {
                List<TeamMemberViewVO> teamMemberViewVOList = new ArrayList<TeamMemberViewVO>();
                teamMemberViewVOList.add(teamMemberViewVO);
                pkEnterAndMemberMap.put(tempPkEnter, teamMemberViewVOList);
            } else {
                pkEnterAndMemberMap.get(tempPkEnter).add(teamMemberViewVO);
            }
        }
        return pkEnterAndMemberMap;
    }

    @Override
    public Map<String, ProjectRefVO> queryRefs(String[] ids) throws BusinessException {
        if (ArrayUtils.isEmpty(ids)) {
            return new HashMap<>();
        }
        //强制截取长度，避免insql可能的问题
        if (ids.length > CommonProgramConsts.DEFAULT_MAX_QUERY_SIZE) {
            ids = Arrays.copyOf(ids, CommonProgramConsts.DEFAULT_MAX_QUERY_SIZE);
        }
        // 这里不作权限控制
        ProjectRefVO[] refs = projectMapper.queryRefVOByIds(ids);
        if (ArrayUtils.isEmpty(refs)) {
            return new HashMap<>();
        }
        Set<String> states = new HashSet<>();
        for (ProjectRefVO ref : refs) {
            states.add(ref.getPkProjectStatus());
        }

        states.remove(null);
        // 处理状态
        if (!states.isEmpty()) {
            //Map集合存入的是key代表项目状态主键，value代表项目状态的名字，例如：立项，创建，施工结算等。
            Map<String, String> statusNameMap = statusQuery.queryNamesByIds(states.toArray(new String[0]));
            for (ProjectRefVO ref : refs) {
                if (ref.getPkProjectStatus() != null) {
                    ref.setProjectStatusName(statusNameMap.get(ref.getPkProjectStatus()));
                }
            }
        }
        Map<String, ProjectRefVO> result = new HashMap<>(refs.length);
        for (ProjectRefVO ref : refs) {
            result.put(ref.getPkProject(), ref);
        }
        return result;
    }

    @Override
    public Map<String, ProjectVO> queryProjects(String[] ids) throws BusinessException {
        if (ArrayUtils.isEmpty(ids)) {
            return new HashMap<>();
        }
        //强制截取长度，避免insql可能的问题
        if (ids.length > CommonProgramConsts.DEFAULT_MAX_QUERY_SIZE) {
            ids = Arrays.copyOf(ids, CommonProgramConsts.DEFAULT_MAX_QUERY_SIZE);
        }

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.addAll(Arrays.asList(ids));

        // 这里不作权限控制
        ProjectVO[] refs = projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));

        setRelationValue(refs);

        if (ArrayUtils.isEmpty(refs)) {
            return new HashMap<>();
        }
        Map<String, ProjectVO> result = new HashMap<>(refs.length);
        for (ProjectVO ref : refs) {
            result.put(ref.getPkProject(), ref);
        }
        return result;
    }

    private void setRelationValue(ProjectVO[] projectVOS) throws BusinessException {
        if(projectVOS == null || projectVOS.length <= 0){
            return;
        }

        Set<String> pkProjectStateSet = new HashSet<>();
        for(ProjectVO projectVO : projectVOS){
            pkProjectStateSet.add(projectVO.getPkProjectStatus());
        }

        Map<String, String> statusNameMap = statusQuery.queryNamesByIds(pkProjectStateSet.toArray(new String[]{}));
        for (ProjectVO projectVO : projectVOS) {
            if (projectVO.getPkProjectStatus() != null) {
                projectVO.setProjectStatusName(statusNameMap.get(projectVO.getPkProjectStatus()));
            }
        }
    }

    @Override
    public ProjectVO[] queryProjectByTenant(String tenantid, Byte state) throws BusinessException {
        if (tenantid == null)
            return new ProjectVO[0];

        return projectMapper.queryProjectByTenant(tenantid, state);
    }

    @Override
    public ProjectBillStatisticsVO[] queryStatistics(String projectId) throws BusinessException {
        // 构造统计信息
        if (StringUtils.isEmpty(projectId)) {
            return null;
        }
        return statisticsMapper.queryByProject(projectId);
    }

    @Override
    public Map<String, String> queryProjectTypesByProjects(String[] pkProjects) throws BusinessException {
        if (ArrayUtils.isEmpty(pkProjects))
            return new HashMap<>();

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.addAll(Arrays.asList(pkProjects));
        ProjectVO[] typeVOs = projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));
        if (ArrayUtils.isEmpty(typeVOs))
            return new HashMap<>();
        Map<String, String> result = new HashMap<>(typeVOs.length);
        for (ProjectVO vo : typeVOs) {
            if(StringUtils.isNotEmpty(vo.getPkProjectType()))
                result.put(vo.getPkProject(), vo.getPkProjectType());
        }
        return result;
    }

    @Override
    public Map<String, String> queryProjectStatusByProjects(String[] pkProjects) throws BusinessException {
        if (ArrayUtils.isEmpty(pkProjects))
            return null;

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.addAll(Arrays.asList(pkProjects));
        ProjectVO[] statusVOs = projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));
        if (ArrayUtils.isEmpty(statusVOs))
            return new HashMap<>();
        Map<String, String> result = new HashMap<>(statusVOs.length);
        for (ProjectVO vo : statusVOs) {
            if(StringUtils.isNotEmpty(vo.getPkProjectStatus()))
                result.put(vo.getPkProject(), vo.getPkProjectStatus());
        }
        return result;
    }

    @Override
    public String queryProjectStatusByProject(String pkProject) throws BusinessException {
        if(StringUtils.isEmpty(pkProject)){
            return "";
        }

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.add(pkProject);
        ProjectVO[] projectVOs = projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));

        if(ArrayUtils.isNotEmpty(projectVOs)) {
            return projectVOs[0].getPkProjectStatus();
        }
        return "";
    }

    @Override
    public String queryProjectTypeByProject(String pkProject) throws BusinessException {
        if(StringUtils.isEmpty(pkProject)){
            return "";
        }

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.add(pkProject);

        ProjectVO[] projectVOs = projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));

        if(ArrayUtils.isNotEmpty(projectVOs)) {
            return projectVOs[0].getPkProjectType();
        }
        return "";
    }

    @Override
    public Map<String, String> queryProjectNameByIds(String[] ids) throws BusinessException {
        Map<String, String> results = new HashMap<>();
        if (ArrayUtils.isEmpty(ids))
            return results;

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.addAll(Arrays.asList(ids));
        ProjectVO[] projectVOs = projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));
        if (ArrayUtils.isEmpty(projectVOs)) {
            return results;
        }
        for (ProjectVO vo : projectVOs) {
            results.put(vo.getPkProject(), vo.getSname());
        }
        return results;
    }

    @Override
    public List<ProjectVO> queryProjectsByFuzzyName(String fuzzyName, String pkTenant) throws BusinessException {
        return projectMapper.queryProjectsByFuzzyName(fuzzyName, pkTenant);
    }

    @Override
    public Map<String, List<ProjectVO>> queryProjectsByOrgs(String pkTenant, String[] pkOrgs) {

        if (ArrayUtils.isEmpty(pkOrgs))
            return new HashMap<String, List<ProjectVO>>();

        ProjectVO[] projectVOs = projectMapper.queryPrjByOrgs(pkTenant, pkOrgs, null);

        Map<String, List<ProjectVO>> projectVOMap = new HashMap<String, List<ProjectVO>>();

        for (ProjectVO projectVO : projectVOs) {
            if (projectVOMap.get(projectVO.getPkOrg()) == null) {
                List<ProjectVO> projectVOList = new ArrayList<ProjectVO>();
                projectVOMap.put(projectVO.getPkOrg(), projectVOList);
            }
            projectVOMap.get(projectVO.getPkOrg()).add(projectVO);
        }

        return projectVOMap;
    }

    @Override
    public String[] queryProjectIdByTenantOrg(String keyword, String tenant, String org) {
        return projectMapper.searchProjectIdByTenantOrg(keyword, tenant, org, null);
    }
    @Override
    public ProjectVO[] queryProjectIdByTenantOrgExt(String tenant, String org) {
        return projectMapper.searchProjectIdByTenantOrgExt(tenant, org);
    }

    @Override
    public ProjectVO[] queryPMCProjects(String pkTenant) {

        if (StringUtils.isEmpty(pkTenant))
            return new ProjectVO[0];

        return projectMapper.queryPMCProject(pkTenant);
    }

    @Override
    public ProjectVO[] queryVOByIds(String[] ids) throws BusinessException {
        if(ids == null || ids.length <= 0){
            return new ProjectVO[]{};
        }

        Set<String> pkProjectSet = new HashSet<>();
        pkProjectSet.addAll(Arrays.asList(ids));
        return projectMapper.queryVOByIds(BulkDataSplitUtils.getSplitDataSet(pkProjectSet));
    }

    @Override
    public String[] queryProjectIdsByOrgs(String pkTenant, String[] orgIds) throws BusinessException {
        if (ArrayUtils.isEmpty(orgIds))
            return new String[0];

        return projectMapper.queryProjectIdsByOrgs(pkTenant, orgIds);
    }

    @Override
    public Boolean quote(String pkTenant, String code, String[] ids) {
        int quote = projectMapper.quote(pkTenant, code, ids);
        if (quote==0){
            return false;
        }
        return true;
    }

    @Override
    public Map<String, Object> queryProjectBoardById(String projectId,String pkPlan) throws BusinessException {

        //通过主键查询项目对象
        ProjectVO projectVO = projectMapper.getById(projectId);

        if(projectVO.getPkOrg() != null){
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), projectVO.getPkOrg());
            if(organizationVO != null) projectVO.setOrgName(organizationVO.getSname());
        }

        //查询项目下的所有子计划并取第一个子计划查询里程碑信息
        List<ScheduleVO> scheduleVOS = scheduleQueryService.queryByPkProject(projectVO.getPkProject());
        //ProjectPlanViewVO[] projectPlanVOS = projectPlanQuery.queryViewByProject(projectVO.getPkProject());
        projectVO.setProjectPlanVOS(scheduleVOS.toArray(new ScheduleVO[0]));

        //如果 pkPlan 为空 获取第一个根计划的pkPlan
        if(StringUtils.isEmpty(pkPlan)) {
            if (scheduleVOS == null || scheduleVOS.size() == 0) return null;
            pkPlan = scheduleVOS.get(0).getPkSchedule();
            projectVO.setProgress(scheduleVOS.get(0).getProgress());
        } else {
            for (ScheduleVO scheduleVO : scheduleVOS) {
                if (pkPlan.equals(scheduleVO.getPkSchedule())) {
                    projectVO.setProgress(scheduleVO.getProgress());
                }
            }
        }

        //返回所有项目的里程碑对象数据
        ScheduleItemVO[] scheduleItemVOS = scheduleItemQueryService.queryMileStonePlan(pkPlan);

        HashMap<String, Object> result = new HashMap<>();

        result.put("projectVO",projectVO);
        result.put("millStoneProgs",scheduleItemVOS);

        return result;
    }

    @Override
    public Map<String, Object> queryPlanBoardByProSrcId(String pkProSrc) throws BusinessException {
        HashMap<String, Object> result = initResultMap();

        ProjectVO projectVO = queryByPkSrc(RuntimeEnvironment.getTenantId(),pkProSrc);
        result.put("projectVO",projectVO);
        if(projectVO == null)
            return result;

        if(projectVO.getPkOrg() != null){
            OrganizationVO organizationVO = organizationQuery.queryByPkSrc(RuntimeEnvironment.getTenantId(), projectVO.getPkOrg());
            if(organizationVO != null) projectVO.setOrgName(organizationVO.getSname());
        }

        //查询项目下的所有子计划并取第一个子计划查询里程碑信息
        List<ScheduleVO> scheduleVOS = scheduleQueryService.queryByPkProject(projectVO.getPkProject());
        //ProjectPlanViewVO[] projectPlanVOS = projectPlanQuery.queryViewByProject(projectVO.getPkProject());
        projectVO.setProjectPlanVOS(scheduleVOS.toArray(new ScheduleVO[0]));

        String pkPlan = "";
        //如果 pkPlan 为空 获取第一个根计划的pkPlan
        if(StringUtils.isEmpty(pkPlan)) {
            if (scheduleVOS == null || scheduleVOS.size() == 0) return result;
            pkPlan = scheduleVOS.get(0).getPkSchedule();
            projectVO.setProgress(scheduleVOS.get(0).getProgress());
        } else {
            for (ScheduleVO scheduleVO : scheduleVOS) {
                if (pkPlan.equals(scheduleVO.getPkSchedule())) {
                    projectVO.setProgress(scheduleVO.getProgress());
                }
            }
        }

        //返回所有项目的里程碑对象数据
        ScheduleItemVO[] scheduleItemVOS = scheduleItemQueryService.queryMileStonePlan(pkPlan);

        result.put("millStoneProgs",scheduleItemVOS);
        return result;
    }

    @Override
    public List<ProjectVO> queryProjectsByTypeAndOrgs(String pkTenant, String pkOrgs, String[] projectTypes, String[] projectIds) {
        List<ProjectVO> projectVOS = projectMapper.queryProjectsByTypeAndOrgs(pkTenant, pkOrgs, projectTypes, projectIds);
        return projectVOS;
    }

    /**
     * 为了前端展示结构正常
     *
     * @return
     */
    private HashMap<String, Object> initResultMap() {
        HashMap<String, Object> result = new HashMap<>();
        result.put("projectVO",null);
        result.put("millStoneProgs",new ProjectPlanViewVO[0]);
        return result;
    }
}
